home *** CD-ROM | disk | FTP | other *** search
- PROCEDURE SBomber; {Stealth Bomber}
- {
- Author: David Malmberg
-
- Strategy: Place bombs in the middle of the field then go to a random
- corner with cloak raised. Scan for an enemy near the bomb. If you
- spot one, then detonate the bomb and begin again with another bomb.
-
- If you see an enemy in missile range (but not near the bomb) blast 'em.
- }
-
- (* Below are the SBomber options as specified in the SBOMBER.CFG file
-
- Radar := 3;
- Fuel := 0;
- Engine := 0;
- Armor := 0;
- Warheads := 1;
- Bombs := 1;
- Shielding := 0;
- Cloaking := 5;
- Repairing := 0;
- *)
-
- CONST
- NW_Corner = 1;
- NE_Corner = 2;
- SW_Corner = 3;
- SE_Corner = 4;
-
- VAR { SBomber "Global" variables }
-
- Angle, { Scanning angle }
- Last_Damage, { Robot's Last damage value }
- D_Speed, { Robot's desired speed }
- D_Heading, { Robot's desired heading }
- BombX, BombY, {Bomb's Co-ordinates}
- BombAngle, BombRange, {Angle and Distance from current corner to Bomb}
- LastTime, { Last Time cycles were measured }
- Delta : Integer; { Scanning arc }
-
- CornerX : ARRAY[1..4] OF Integer; {X coordinate of Corners}
- CornerY : ARRAY[1..4] OF Integer; {Y coordinate of Corners}
- StartAngle : ARRAY[1..4] OF Integer; {Starting scanning angles for Corners}
-
- Corner, { Current Corner }
- Range { Range/Distance to foe } : Integer;
-
- BombHasExploded : Boolean;
-
- PROCEDURE Initialize;
- BEGIN
- CornerX[NW_Corner] := 10;
- CornerY[NW_Corner] := 990;
- StartAngle[NW_Corner] := 270;
-
- CornerX[NE_Corner] := 990;
- CornerY[NE_Corner] := 990;
- StartAngle[NE_Corner] := 180;
-
- CornerX[SW_Corner] := 10;
- CornerY[SW_Corner] := 10;
- StartAngle[SW_Corner] := 0;
-
- CornerX[SE_Corner] := 990;
- CornerY[SE_Corner] := 10;
- StartAngle[SE_Corner] := 90;
- END; {Initialize}
-
- PROCEDURE Aim(VAR Ang : Integer; VAR Arc : Integer);
- {
- Improve aim by doing a binary search of the target area.
- I.E., divide the target area in two equal pieces and redefine
- the target area to be the piece where the foe is found.
- If the foe is not found, expand the search area to the
- maximum arc of plus or minus 10 degrees.
- }
- BEGIN
- Arc := Arc DIV 2; { Divide search area in two. }
- IF scan(Ang-Arc, Arc) <> 0 { Check piece "below" target angle. }
- THEN Ang := Ang-Arc { If foe found, redefine target angle. }
- ELSE IF scan(Ang+Arc, Arc) <> 0 { Check piece "above" target angle. }
- THEN Ang := Ang+Arc { If foe found, redefine target angle. }
- ELSE Arc := 10;
- { Foe not found in either piece, expand search area to maximum arc. }
- END; {Aim}
-
- PROCEDURE BlastThem;
- BEGIN
- Angle := 10;
- REPEAT
- Delta := 10; { Start with widest scanning arc. }
- Range := scan(Angle, Delta);
- WHILE (Range > 40) AND (ObjectScanned = Enemy)
- AND (Range < MaxMissileRange) DO
- { Must be far enough away to avoid self-damage. }
- BEGIN
- Aim(Angle, Delta); { Improve aim. }
- Cannon(Angle, Range); { Fire!! }
- Range := scan(Angle, Delta); { Is foe still in sights? }
- END;
- Angle := Angle+20; { Look in adjacent target area. }
- UNTIL Angle > 360;
- END;
-
- PROCEDURE GOTO(x, y : Integer);
- { Go to location X,Y on playing field. }
- VAR Heading : Integer;
- BEGIN
- LowerCloak; {Less need for Cloak while moving}
-
- { Find the heading we need to get to the desired spot. }
- Heading := Angle_To(x, y);
-
- { Keep traveling at top speed until we are within 150 meters }
- WHILE (distance(loc_x, loc_y, x, y) > 150) DO
- BEGIN
- Drive(Heading, MaxSpeed);
- BlastThem;
- END;
-
- { Cut speed, and creep the rest of the way. }
- WHILE (distance(loc_x, loc_y, x, y) > 20) DO
- BEGIN
- Drive(Heading, 20);
- BlastThem;
- END;
-
- { Stop driving, should coast to a stop. }
- Drive(Heading, 0); {I.E., Stop}
- RaiseCloak; {Need Cloak while stopped}
- END; {GoTo(X,Y)}
-
- FUNCTION Hurt : Boolean;
- { Checks if Robot has incurred at least 5 points of new damage. }
- VAR Curr_Damage : Integer;
- Answer : Boolean;
- BEGIN
- Curr_Damage := damage;
- Answer := (Curr_Damage > (Last_Damage + 4));
- Last_Damage := Curr_Damage;
- IF Answer THEN LastTime := Time;
- Hurt := Answer;
- END; {Hurt}
-
- PROCEDURE PlaceTheBomb;
- BEGIN {PlaceTheBomb}
- BombHasExploded := FALSE;
- GoTo(500,500);
- BombX := Loc_X;
- BombY := Loc_Y;
- PlaceBomb;
- END; {PlaceTheBomb}
-
- FUNCTION EnemyNearBomb : Boolean;
- CONST PlusMinus = 200;
- VAR EnemyDistance : Integer;
- Answer : Boolean;
- BEGIN
- Answer := FALSE;
- EnemyDistance := Scan(BombAngle, 10);
- IF ObjectScanned <> Enemy THEN EnemyDistance := 0;
- IF EnemyDistance > 0
- THEN Answer := (EnemyDistance > (BombRange - PlusMinus))
- AND (EnemyDistance < (BombRange + PlusMinus));
- EnemyNearBomb := Answer;
- END; {EnemyNearBomb}
-
- PROCEDURE Do_Corner;
- BEGIN {Do_Corner}
- Angle := StartAngle[Corner] + 10; {Starting angle for scanning}
- REPEAT
- IF EnemyNearBomb
- THEN BEGIN
- Detonate;
- BombHasExploded := TRUE;
- END;
- Range := scan(Angle, Delta);
- WHILE (Range > 40) AND (Range < MaxRadarRange) DO
- { Must be far enough away to avoid self-damage. }
- BEGIN
- IF ObjectScanned = Enemy THEN cannon(Angle, Range); { Fire!! }
- Range := scan(Angle, Delta); { Is foe still in sights? }
- END;
- Angle := Angle + 20; { Look in adjacent target area. }
- IF (Angle > (StartAngle[Corner] + 90))
- THEN Angle := StartAngle[Corner] + 10;
- UNTIL BombHasExploded;
- END; {Do_Corner}
-
-
- BEGIN {SBomber Main}
- RaiseCloak;
- Initialize;
- Delta := 10; { The widest possible scanning arc. }
- LastTime := Time;
- REPEAT { Until Dead or Winner }
- PlaceTheBomb;
- Corner := Random(3) + 1; {Pick a corner}
- GoTo(CornerX[Corner], CornerY[Corner]);
- { Move to selected corner. }
- BombAngle := Angle_To(BombX, BombY);
- BombRange := Distance(Loc_X, Loc_Y, BombX, BombY);
- { Determine relative location from corner to Bomb }
- Do_Corner;
- IF Hurt THEN
- IF Fuel > 250
- THEN RaiseCloak { Raise cloak and flee! }
- ELSE LowerCloak;
- UNTIL Dead OR Winner;
- END; {SBomber Main}